#ifndef VEC2_H_INCLUDED
#define VEC2_H_INCLUDED

#ifdef USE_DOUBLE_PRECISION
	typedef double slScalar;
#else
	typedef float slScalar;
#endif

struct slVec2;
struct slMat4;

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */
typedef struct slVec2 {
    slScalar m_X;
    slScalar m_Y;
    
#ifdef __CPLUSPLUS

	slVec2();
	slVec2(float x, float y);
	slVec2(const slVec2& vec);

	inline slScalar Length();
	// casting
	operator slScalar* ();
	operator const slScalar* ();

	slVec2& operator+= (const slVec2& vec);

	slVec2& operator-= (const slVec2& vec);

	slVec2& operator*= (slScalar s);

	slVec2& operator/= (slScalar s);

	slVec2 operator+ () const;

	slVec2 operator- () const;
	slVec2 operator+ (const slVec2& vec) const;

	slVec2 operator- (const slVec2& vec) const;

	slVec2 operator* (slScalar s) const;

	slVec2 operator/ (slScalar s) const;

	bool operator== (const slVec2& vec) const;

	bool operator!= (const slVec2& vec) const;
#endif
};

#pragma pack(pop)

slScalar slVec2Length(const slVec2* pIn); ///< Returns the length of the vector
slScalar slVec2LengthSq(const slVec2* pIn); ///< Returns the square of the length of the vector
slVec2* slVec2Normalize(slVec2* pOut, const slVec2* pIn); ///< Returns the vector passed in set to unit length
slVec2* slVec2Add(slVec2* pOut, const slVec2* pV1, const slVec2* pV2); ///< Adds 2 vectors and returns the result
slVec2* slVec2Subtract(slVec2* pOut, const slVec2* pV1, const slVec2* pV2); ///< Subtracts 2 vectors and returns the result
slVec2* slVec2Transform(slVec2* pOut, const slVec2* pV1, const slMat4* pM);
slVec2* slVec2TransformCoord(slVec2* pOut, const slVec2* pV, const slMat4* pM); ///<Transforms a 3D vector by a given matrix, projecting the result back into w = 1.
slVec2* slVec2Scale(slVec2* pOut, const slVec2* pIn, const slScalar s); ///< Scales a vector to length s
bool	slVec2AreEqual(const slVec2* p1, const slVec2* p2); ///< Returns true if both vectors are equal






#endif // VEC2_H_INCLUDED
